package com.vxdata.utils.modules.utils.zhjt;

import lombok.extern.slf4j.Slf4j;

import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;

/**
 * ip工具
 */
@Slf4j
public class IpUtil {

    /**
     * 判断字符串是否为IPV4 子网掩码格式
     *
     * @param mask 要验证的子网掩码字符串
     * @return 是 true/ 否 false
     */
    public static boolean isIpMask(String mask) {
        String IP_MASK = "^((128|192)|2(24|4[08]|5[245]))(\\.(0|(128|192)|2((24)|(4[08])|(5[245])))){3}$";
        if (mask == null) return false;
        Pattern pat = Pattern.compile(IP_MASK);
        return pat.matcher(mask).matches();
    }

    /**
     * 根据掩码位数计算掩码
     *
     * @param maskIndex 掩码位
     * @return 子网掩码
     */
    public static String getNetMask(String maskIndex) {
        StringBuilder mask = new StringBuilder();
        int inetMask = 0;
        try {
            inetMask = Integer.parseInt(maskIndex);
        } catch (NumberFormatException e) {
            System.out.println(e.getMessage());
            return null;
        }
        if (inetMask > 32) {
            return null;
        }
        // 子网掩码为1占了几个字节
        int num1 = inetMask / 8;
        // 子网掩码的补位位数
        int num2 = inetMask % 8;
        int[] array = new int[4];
        for (int i = 0; i < num1; i++) {
            array[i] = 255;
        }
        for (int i = num1; i < 4; i++) {
            array[i] = 0;
        }
        for (int i = 0; i < num2; num2--) {
            array[num1] += 1 << 8 - num2;
        }
        for (int i = 0; i < 4; i++) {
            if (i == 3) {
                mask.append(array[i]);
            } else {
                mask.append(array[i]).append(".");
            }
        }
        return mask.toString();
    }

    /**
     * 根据网段计算起始IP 网段格式:x.x.x.x/x
     * 一个网段0一般为网络地址,255一般为广播地址.
     * 起始IP计算:网段与掩码相与之后加一的IP地址
     *
     * @param segment 网段
     * @return 起始IP
     */
    public static String getStartIp(String segment) {
        StringBuilder startIp = new StringBuilder();
        if (segment == null) {
            return null;
        }
        String[] arr = segment.split("/");
        String ip = arr[0];
        String maskIndex = arr[1];
        String mask = getNetMask(maskIndex);
        if (4 != ip.split("\\.").length || mask == null) {
            return null;
        }
        int[] ipArray = new int[4];
        int[] netMaskArray = new int[4];
        for (int i = 0; i < 4; i++) {
            try {
                ipArray[i] = Integer.parseInt(ip.split("\\.")[i]);
                netMaskArray[i] = Integer.parseInt(mask.split("\\.")[i]);
                if (ipArray[i] > 255 || ipArray[i] < 0 || netMaskArray[i] > 255 || netMaskArray[i] < 0) {
                    return null;
                }
                ipArray[i] = ipArray[i] & netMaskArray[i];
                if (i == 3) {
                    startIp.append(ipArray[i] + 1);
                } else {
                    startIp.append(ipArray[i]).append(".");
                }
            } catch (NumberFormatException e) {
                System.out.println(e.getMessage());
            }
        }
        return startIp.toString();
    }

    /**
     * 根据网段计算结束IP
     *
     * @param segment
     * @return 结束IP
     */
    public static String getEndIp(String segment) {
        StringBuilder endIp = new StringBuilder();
        String startIp = getStartIp(segment);
        if (segment == null) {
            return null;
        }
        String[] arr = segment.split("/");
        String maskIndex = arr[1];
        //实际需要的IP个数
        int hostNumber = 0;
        int[] startIpArray = new int[4];
        try {
            hostNumber = 1 << 32 - (Integer.parseInt(maskIndex));
            for (int i = 0; i < 4; i++) {
                assert startIp != null;
                startIpArray[i] = Integer.parseInt(startIp.split("\\.")[i]);
                if (i == 3) {
                    startIpArray[i] = startIpArray[i] - 1;
                    break;
                }
            }
            startIpArray[3] = startIpArray[3] + (hostNumber - 2);
        } catch (NumberFormatException e) {
            System.out.println(e.getMessage());
        }

        if (startIpArray[3] > 255) {
            int k = startIpArray[3] / 256;
            startIpArray[3] = startIpArray[3] % 256;
            startIpArray[2] = startIpArray[2] + k;
        }
        if (startIpArray[2] > 255) {
            int j = startIpArray[2] / 256;
            startIpArray[2] = startIpArray[2] % 256;
            startIpArray[1] = startIpArray[1] + j;
            if (startIpArray[1] > 255) {
                int k = startIpArray[1] / 256;
                startIpArray[1] = startIpArray[1] % 256;
                startIpArray[0] = startIpArray[0] + k;
            }
        }
        for (int i = 0; i < 4; i++) {
            if (i == 3) {
                startIpArray[i] = startIpArray[i] - 1;
            }
            if ("".equals(endIp.toString()) || endIp.length() == 0) {
                endIp.append(startIpArray[i]);
            } else {
                endIp.append(".").append(startIpArray[i]);
            }
        }
        return endIp.toString();
    }

    public static String getSegment(String ip, Integer maskIndex) {
        return ip + "/" + maskIndex;
    }

    public static void main(String[] args) {
        System.out.println(isRemoveIpv4("192.168.20.100"));
        System.out.println(isRemoveIpv4("192.168.20.0"));
        System.out.println(isRemoveIpv4("192.168.255.100"));
        System.out.println(isRemoveIpv4("192.168.1.254"));
    }

    public static String getNetworkStatusByPing(String cmd) {
        //获取当前进程运行对象
        Runtime runtime = Runtime.getRuntime();
        Process process = null;
        String line = null;
        InputStream inputStream = null;
        InputStreamReader isReader = null;
        BufferedReader reader = null;
        String loss = "";//丢包率
        try {
            process = runtime.exec(cmd);
            inputStream = process.getInputStream();//实例化输入流
            isReader = new InputStreamReader(inputStream, "GB2312");
            reader = new BufferedReader(isReader);
            StringBuilder buffer = new StringBuilder();
            String os = System.getProperty("os.name").toLowerCase();
            if (os.contains("win")) {//Windows系统执行结果解析
                while ((line = reader.readLine()) != null) {
                    //丢包率
                    if (line.contains("%")) {
                        loss = line.substring(line.lastIndexOf("=") + 1, line.indexOf("%") + 1);
                        if (loss.contains("(")) {
                            loss = loss.substring(loss.indexOf("(") + 1).trim();
                        }
                    }
                }
            } else {
                //Linux系统执行结果解析
                while ((line = reader.readLine()) != null) {
                    //丢包率
                    if (line.contains("%")) {
                        String[] msg = null;
                        if (line.contains(",")) {
                            msg = line.split(",");
                        } else if (line.contains("，")) {
                            msg = line.split("，");
                        }
                        assert msg != null;
                        if (msg.length > 0) {
                            loss = msg[2].substring(0, msg[2].indexOf("%") + 1).trim();
                        }
                    }
                }
            }
            inputStream.close();
            isReader.close();
            reader.close();
        } catch (IOException e) {
            log.error("通过ping方式获取网络信息异常：" + e.getMessage());
            e.printStackTrace();
            runtime.exit(1);
        }
        return loss;
    }

//    /**
//     * 调用python脚本测试连通
//     *
//     * @param ipList ip集合
//     * @return 返回结果
//     */
//    public static String ipBatchDealPy(List<String> ipList) {
//        String ipStr = StrUtil.join(",", ipList);
//        String resultStr = null;
//        try {
//            URL url = ResourceUtils.getURL("classpath:py/ipBatchDeal.py");
//
//            String[] params = new String[]{"python", url.getPath().substring(1), ipStr};
//            Process proc = Runtime.getRuntime().exec(params); //执行py文件
//            InputStreamReader stdin = new InputStreamReader(proc.getInputStream());
//            LineNumberReader input = new LineNumberReader(stdin);
//            String line;
//            while ((line = input.readLine()) != null) {
//                resultStr = line;
//            }
//            int re = proc.waitFor();
//            if (re == 0) {
//                return resultStr;
//            } else {
//                System.out.println("python脚本执行出错");
//            }
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//        return resultStr;
//    }

    public static String ipBatchDealCmd(List<String> ipList) {
        String resultStr = null;
        try {
            String cmd;
            for (String ip : ipList) {
                cmd = "ping -n 4 -4 " + ip;
                Process proc = Runtime.getRuntime().exec(cmd);
                InputStreamReader stdin = new InputStreamReader(proc.getInputStream());
                LineNumberReader input = new LineNumberReader(stdin);
                String line;
                while ((line = input.readLine()) != null) {
                    resultStr = line;
                }
                int re = proc.waitFor();
                if (re == 0) {
                    return resultStr;
                } else {
                    System.out.println("cmd执行出错");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return resultStr;
    }

    public static Boolean isRemoveIpv4(String ipv4) {
        String[] split = ipv4.split("\\.");
        String s = split[split.length - 1];
        List<String> excludeIpList = new ArrayList<>();
        excludeIpList.add("0");
        excludeIpList.add("254");
        excludeIpList.add("255");
        return excludeIpList.contains(s);
    }


}
